Exercises Section 12.3.1
Exercise 12.27: The TextQuery and QueryResult classes use only
capabilities that we have already covered. Without looking ahead, write your
own versions of these classes.
TextQuery和QueryResult類別會用到的功能並不會超出我們已經討論過的範圍。在繼續閱讀本書前,針對這兩個類別,先試著依照我們談過的功能寫出你自己版本的TextQuery和QueryResult。
https://play.google.com/books/reader?id=J1HMLyxqJfgC&pg=GBS.PT902
https://drive.google.com/open?id=140Kwtzv7xCWploxvSN41MHlHmXd4VUO-
臉書直播:
https://www.facebook.com/oscarsun72/videos/2569013886543063
約在 2:09:00處
瞧瞧當時成功時的驚喜若狂 呵呵
感恩感恩 讚歎讚歎 南無阿彌陀佛
Youtube實境秀:
相關文章
#include<iostream>
#include<memory>
#include <fstream>
#include"TextQuery.h"
#include"QueryResult.h"
using namespace std;
pair<shared_ptr<vector<string>>,shared_ptr<map<string,set<size_t>>>> queryData(ifstream& infile)
{
string lStr;
size_t line_Num{ 0 };
vector<string>vs;//主要就是這兩個(vector、map)容器要作為TexQuery與QueryResult資源共享者
map<string, set<size_t>>word_lineNum;
shared_ptr<vector<string>>spVs(make_shared<vector<string>>(vs));//利用智慧指標shared_ptr來達到
shared_ptr<map<string, set<size_t>>>spWord_lineNum(
make_shared<map<string,set<size_t>>>(word_lineNum));//資源共用的目的
while (infile && !infile.eof())//第98集6:46:00
{
getline(infile, lStr);
spVs->push_back(lStr);//one line of text in an element
++line_Num;
istringstream isstr(lStr);
string word;
while (isstr >> word)
{
map<string, set<size_t>>::iterator mIter = spWord_lineNum->find(word);
if (mIter == spWord_lineNum->end()) {//如果文字行號的map還沒有此文字的話
set<size_t> line_num_st;
line_num_st.insert(line_Num);
spWord_lineNum->insert(make_pair(word, line_num_st));
}
else//如果文字行號的map已經有此文字的話
mIter->second.insert(line_Num);//若原已有此行號,用insert就不會插入(何況set本來鍵值(就是「值」)就不能重複
}
}
return make_pair(spVs,spWord_lineNum);
}
int main() {
string fName,strSearch;
cout << "請指定要檢索的檔案全名(fullname,含路徑與副檔名)" << endl;
if (cin >> fName);
//必須檢查檔案存不存在
else//若沒有指定檔案的話
{
fName = "V:\\Programming\\C++\\input.txt";
}
cin.clear();//cin前面已經移動它的迭代器(iterator)了到讀取失敗的位置,故要歸零清除,
//否則如果這裡讀取失敗,後面的cin >> strSearch判斷就會永遠都是false(讀取失敗)了
//第89集1:4:00//可參考前面談資料流(stream)的部分
ifstream ifs(fName);
TextQuery tq(queryData(ifs));
while(true){
cout << "請輸入檢索字串,或輸入「q」離開" << endl;
if (!(cin >> strSearch) || strSearch == "q") break;
QueryResult qr= tq.query(strSearch);
qr.print();
}
}
#ifndef TextQuery_H
#define TextQuery_H
#include<vector>
#include<memory>
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>//要用getline函式,要引入這一行
#include<map>
#include<set>
#include "QueryResult.h"
using namespace std;
class TextQuery
{
friend class QueryResult;
typedef pair<map<string, size_t>::const_iterator, map<string, size_t>::const_iterator>
pair_iterator_map;
typedef pair<shared_ptr<vector<string>>, shared_ptr<pair<string, set<size_t>>>> pair_sp_vec_str_sp_pair_str_set;
using iterator_map= map<string, set<size_t>>::iterator;
public:
//TextQuery() ;
TextQuery(ifstream& infile);
TextQuery(pair<shared_ptr<vector<string>>, shared_ptr<map<string, set<size_t>>>>spPair):
spVs(spPair.first),word_lineNum(*spPair.second){};
~TextQuery();
QueryResult query(const string&);
private:
shared_ptr<vector<string>>spVs;//第89集 2:12:00
//一個map關聯式容器(associative container)因為一個字詞key(string)會有好幾行與之對應,故用
//map,而其「值」為set容器
map<string, set<size_t>>word_lineNum;
};
TextQuery::TextQuery(ifstream& infile)
{
string lStr;
size_t line_Num{ 0 };
vector<string>vs;
spVs = make_shared<vector<string>>(vs);
while (infile && !infile.eof())//第89集2:4:00
{
getline(infile, lStr);
spVs->push_back(lStr);//one line of text in an element
++line_Num;
istringstream isstr(lStr);
string word;
while (isstr >> word)
{
map<string, set<size_t>>::iterator mIter = word_lineNum.find(word);
if (mIter == word_lineNum.end()) {//如果文字行號的map還沒有此文字的話
set<size_t> line_num_st;
line_num_st.insert(line_Num);
word_lineNum.insert(make_pair(word, line_num_st));
}
else//如果文字行號的map已經有此文字的話
mIter->second.insert(line_Num);//若原已有此行號,用insert就不會插入(何況set本來鍵值(就是「值」)就不能重複
}
}
}
TextQuery::~TextQuery()
{
}
QueryResult TextQuery::query(const string& wordForQuery)
{
/*第88集4:18:23//4:31:30回傳的應該是檢索結果,
*(此行註文但作參考)或者試用allocator物件記錄在動態記憶體(dynamic memory),再與QueryResult物件共用此資料*/
//臉書直播第443集、444集。第89集1:18:00
iterator_map wlIter = word_lineNum.find(wordForQuery);
if (wlIter == word_lineNum.end())
{
cout << "沒有找到您要找的字串!" << endl;
set<size_t>st;
return QueryResult(make_shared<pair<string, set<size_t>>>
(make_pair(wordForQuery,st)));//()呼叫運算子(call operator)這裡表示呼叫預設建構器(default constructor)
}
//shared_ptr<pair<string, set<size_t>>> sp = make_shared<pair<string,set<size_t>>>(*wlIter);
//QueryResult qrfound(spVs, sp);
return QueryResult(spVs,make_shared<pair<string,set<size_t>>>(*wlIter));//「()」:呼叫建構器
#ifndef QueryResult_H
#define QueryResult_H
#include<vector>
#include<memory>
#include<iostream>
#include<iterator>
#include"TextQuery.h"
using namespace std;
class QueryResult
{
public:
QueryResult(shared_ptr<pair<string,set<size_t>>>sp_key) :pair_str_set(sp_key) { found = false; }
QueryResult(shared_ptr<vector<string>>, shared_ptr<pair<string, set<size_t>>>);
~QueryResult();
void print();
private:
shared_ptr<vector<string>>vs;
shared_ptr<pair<string, set<size_t>>>pair_str_set;
bool found;
};
QueryResult::QueryResult(shared_ptr<vector<string>> sp_vec_str, shared_ptr<pair<string, set<size_t>>> sp_pair_str_set)
{
vs = sp_vec_str;//這樣才是由智慧指標(smart pointer)來管理,而不是
//vs=*sp_vec_str ←原來寫這樣,就是解參考智慧指標後再把解參考的結果容器,指定(即複製一份)
//給「vs」這個資料成員;這樣就不合資源共享(共用資源)的原則,反而成複製一份了。第98集2:40:00
pair_str_set = sp_pair_str_set;
found = true;
}
QueryResult::~QueryResult()
{
}
inline void QueryResult::print()
{
ostream_iterator<string>o(cout);
ostream_iterator<size_t>o_size_t(cout);
*o++ = pair_str_set->first;
*o++ = " occurs ";
if (!found)
*o++ = "0 time";
else//如果有找到
{
*o_size_t++ = pair_str_set->second.size();
*o++ = (pair_str_set->second.size() > 1) ? " times" : " time";
cout << endl;
for (const size_t i : pair_str_set->second)
{
*o++ = "\t(line ";
*o_size_t++ = i;
*o++ = ")";
*o++ = (*vs)[i - 1];
cout << endl;
}
}
cout << endl;
}
#endif // !QueryResult_H
https://github.com/oscarsun72/prog1-C-Primer-5th-Edition-s-Exercises/branches
C++自修入門實境秀 508 重新譯撰 《C++ Primer 5th》
Chapter 12. Dynamic Memory
12.3 Using the Library: A Text-Query Program 12.3.1. Design of the Query Program
練習12.27 再複習12章,試用 allocator ,以動態配置的物件(dynamically allocated object)來改寫
上一集:
https://www.facebook.com/100003034306665/videos/2578200402291078
下一集:
緣起:http://bit.ly/2XwHOUH
全部:http://bit.ly/2NoA2ID 原檔下載:http://bit.ly/2Ixe2Vc
課文: http://bit.ly/2FIHV57
http://bit.ly/2mttmfa(第二篇)
第10章: http://bit.ly/2MuPmiZ
章12、13: http://bit.ly/2r7qSW7
重譯12章:http://bit.ly/2G2fPSg (docx) http://bit.ly/2V8UgZ7
重譯11章:http://bit.ly/39P7HRU
https://play.google.com/books/reader?id=J1HMLyxqJfgC&pg=GBS.PT902
講義下載:
http://bit.ly/2khF8Ic (全部)
程式碼:
https://github.com/oscarsun72/prog1
————————————————
版权声明:本文为CSDN博主「任真」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/oscarsun72/article/details/104446129